﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WPFByCoreApp
{
    /// <summary>
    /// Interaction logic for TestNewDataGridWindow.xaml
    /// </summary>
    public partial class TestNewDataGridWindow : Window
    {
        public TestNewDataGridWindow()
        {
            InitializeComponent();

            this.DataContext = new MainViewModel();
            this.Loaded += TestNewDataGridWindow_Loaded;
            this.dg1.CurrentCellChanged += Dg1_CurrentCellChanged;
            this.dg1.SelectedCellsChanged += Dg1_SelectedCellsChanged;
            this.dg1.LoadingRow += Dg1_LoadingRow;
            this.dg1.RowEditEnding += Dg1_RowEditEnding;
            //this.dg1.SelectionUnit = DataGridSelectionUnit.CellOrRowHeader;
            this.dg1.SelectionChanged += Dg1_SelectionChanged;

            this.dg1.EditCompleted = EditCompleted;



            this.dg1.AddHandler(DataGridCell.GotFocusEvent, new RoutedEventHandler(Cell_GotFocus));

            InputMethod.Current.StateChanged += (sender, e) =>
            {
                if (e.IsImeStateChanged && (sender is InputMethod) && (sender as InputMethod).ImeState == InputMethodState.On)
                {
                    Task.Run((Action)delegate
                    {
                        this.Dispatcher.BeginInvoke((Action)delegate
                        {
                            InputMethod.Current.ImeState = InputMethodState.Off;
                        });
                    });
                }
            };
            if (Application.Current.Resources.Contains("key1"))
                Application.Current.Resources.Remove("key1");
            Application.Current.Resources.Add("key1", "start");
            type = 1;


            List<string> list = new List<string>();

            list.Sort(string.Compare);

 
        }

        private void Dg1_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
        {

        }

        private void Dg1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void Dg1_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            //if (e.Row.Item is ViewModelBase)
            //{
            e.Row.Header = e.Row.GetIndex() + 1;
            //}
            //else // Row is {NewItemPlaceholder}
            //{
            //    e.Row.Header = "✲";
            //}
            if (this.dg1.Items.Count > 0)
            {
                var row = this.dg1.GetRow(this.dg1.Items.Count - 1);
                if (row != null)
                {
                    row.Header = this.dg1.Items.Count;
                }
            }
        }

        private void Dg1_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
        {

        }

        private void Dg1_CurrentCellChanged(object sender, EventArgs e)
        {

        }

        private void TestNewDataGridWindow_Loaded(object sender, RoutedEventArgs e)
        {
            InputMethod.Current.ImeState = InputMethodState.Off;

        }


        private void Cell_GotFocus(object sender, RoutedEventArgs e)
        {
            if (dg1.IsCell(e.OriginalSource as UIElement))
            {


            }
        }

        DataGridCell cell = null;

        int type = 0;

        private void Button_Click(object sender, RoutedEventArgs e)
        {

            //if (cell == null)
            //    cell = dg1.GetCell(0, 0);

            //cell.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));


            //cell = dg1.GetDataGridCell(dg1.CurrentCell);

            //MainViewModel mainViewModel = this.DataContext as MainViewModel;
            //if (mainViewModel != null)
            //{
            //    mainViewModel.Update();

            //}


            //if (Application.Current.Resources.Contains("key1"))
            //    Application.Current.Resources.Remove("key1");


            //if (type == 0)
            //{
            //    Application.Current.Resources.Add("key1", "start");
            //    type = 1;
            //}
            //else
            //    Application.Current.Resources.Add("key1", "开始");


            //cell = dg1.GetCell(0, 0);
            //cell.Focus();

            //dg1.LostFocusNew();


            //if (Application.Current.Resources.Contains("fontSize"))
            //    Application.Current.Resources.Remove("fontSize");

            //if (type == 0)
            //{
            //    Application.Current.Resources.Add("fontSize", 22d);
            //    type = 1;
            //}
            //else
            //{
            //    Application.Current.Resources.Add("fontSize", 8d);
            //    type = 0;
            //}

            //this.dg1.CanUserAddRows = !this.dg1.CanUserAddRows;


        }

        private void MUpDownTextBox_Up(object sender, RoutedEventArgs e)
        {
            //MUpDownTextBox mUpDownTextBox = sender as MUpDownTextBox;
            //var bind = mUpDownTextBox.GetBindingExpression(TextBox.TextProperty);
            //bind.ParentBinding.Path.Path

        }

        private void EditCompleted()
        {
            //if (((MainViewModel)this.DataContext).CurPoinits < ((MainViewModel)this.DataContext).MaxPoinits)
            //{
            //    this.dg1.BeginEdit();
            //    this.dg1.UpdateLayout();
            //}
            //else
            //    this.dg1.CanUserAddRows = false;

        }

        private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
        {
           
        }
    }



    public enum DisplayDataEnum
    {
        HZ,
        time
    }


    public class MainViewModel : ViewModelBase
    {



        private ViewModel copyViewModel;


        private ViewModel _currentItem;

        public int MaxPoinits
        {
            get
            {
                return 1000;
            }
        }

        public int CurPoinits
        {
            get
            {
                int numPoinis = 0;

                List.ToList().ForEach(par =>
                {
                    numPoinis += par.dataInfo.point;
                });


                return numPoinis;
            }
        }


        private bool _isCanUserAddRows = true;

        public bool IsCanUserAddRows
        {
            get
            {
                return _isCanUserAddRows && List.Count != 2;
            }
            set
            {
                _isCanUserAddRows = value;
                RaisePropertyChanged();
            }
        }


        //private bool _isEdit;

        //public bool IsEdit
        //{
        //    get
        //    {
        //        return _isEdit;
        //    }
        //    set
        //    {
        //        _isEdit = value;
        //        RaisePropertyChanged();
        //    }

        //}

        private bool IsBackGround = false;

        private object _selectedVM;

        public object SelectedVM
        {
            get
            {
                return _selectedVM;
            }
            set
            {
                _selectedVM = value;
                RaisePropertyChanged();
            }
        }


        private object _curItem;

        public object CurItem
        {

            get
            {
                return _curItem;
            }
            set
            {
                _curItem = value;
                RaisePropertyChanged();
            }
        }


        public ObservableCollection<ViewModel> List { get; set; }

        public ICommand CopyCommand { private set; get; }

        public ICommand PasteCommand { private set; get; }

        public ICommand InsertCommand { private set; get; }

        public ICommand DelCommand { private set; get; }

        public ICommand ClearCommand { private set; get; }

        public ICommand AddingNewItemCommand { private set; get; }


        public Action action;

        public event Action myevent;


        public List<string> Points { get; set; }


        public MainViewModel()
        {
            List = new ObservableCollection<ViewModel>();

            Points = new List<string>() { "10", "100", "1000" };

            List.CollectionChanged += List_CollectionChanged;
            CopyCommand = new RelayCommand(ExcuteCopy);
            PasteCommand = new RelayCommand(ExcutePaste);
            InsertCommand = new RelayCommand(ExcuteInsert);
            DelCommand = new RelayCommand(ExcuteDel);
            ClearCommand = new RelayCommand(ExcuteClear);
            AddingNewItemCommand = new RelayCommand<object>(ExcuteAddingNewItemCommand);
        }

        private void List_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if (e.NewItems != null && e.NewItems.Count > 0)
                    {
                        foreach (ViewModel item in e.NewItems)
                        {
                            if (item != null)
                            {
                                item.PropertyChanged += Item_PropertyChanged;

                                //this.action = new Action(item.Show);
                                //this.myevent += item.Show;
                            }

                        }

                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    if (e.OldItems != null && e.OldItems.Count > 0)
                    {
                        foreach (ViewModel item in e.OldItems)
                        {
                            if (item != null)
                                item.PropertyChanged -= Item_PropertyChanged;
                        }

                    }
                    break;
            }

            RaisePropertyChanged("IsCanUserAddRows");
        }


        private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (!IsBackGround)
            {
                //if (e.PropertyName.Equals("point"))
                //{
                //    Task.Run(() =>
                //    {
                //        int num = 0;
                //        while (num < 1000)
                //        {
                //            if (!IsEdit)
                //            {
                //                Application.Current.Dispatcher.Invoke((Action)delegate
                //                {
                //                    EditCompleted();
                //                });
                //                break;
                //            }

                //            num++;
                //            Thread.Sleep(10);
                //        }
                //    });

                //}
            }
        }

        private void ExcuteCopy()
        {
            if (SelectedVM is ViewModel)
            {
                copyViewModel = SelectedVM as ViewModel;
            }
        }

        private void ExcutePaste()
        {
            if (SelectedVM != null && copyViewModel != null)
            {
                if (SelectedVM is ViewModel)
                {
                    int index = List.IndexOf((SelectedVM as ViewModel));

                    List.Insert(index, (ViewModel)copyViewModel.Clone());
                }
                else if (SelectedVM.Equals(CollectionView.NewItemPlaceholder))
                {
                    List.Add((ViewModel)copyViewModel.Clone());
                }

                copyViewModel = null;
            }
        }

        private void ExcuteInsert()
        {
            if (SelectedVM == null && List.Count == 0)
            {
                List.Add(new ViewModel(new DataInfo(), DisplayDataEnum.HZ));
            }
            else if (SelectedVM != null && SelectedVM.Equals(CollectionView.NewItemPlaceholder) || SelectedVM == null)
            {
                if (List.Count == 0)
                {
                    List.Add(new ViewModel(new DataInfo(), DisplayDataEnum.HZ));
                }
                else
                {
                    List.Add((ViewModel)List[List.Count - 1].Clone());
                }
            }
            else if (SelectedVM is ViewModel)
            {
                var tempVM = SelectedVM as ViewModel;
                int index = List.IndexOf(tempVM);
                int copyindex = index - 1;
                if (copyindex < 0)
                {
                    List.Insert(0, new ViewModel(new DataInfo(), DisplayDataEnum.HZ));
                }
                else
                {
                    List.Insert(index, (ViewModel)List[copyindex].Clone());
                }
            }
        }

        private void ExcuteDel()
        {
            if (SelectedVM is ViewModel)
            {
                List.Remove((SelectedVM as ViewModel));
            }
        }

        private void ExcuteClear()
        {
            foreach (ViewModel item in List)
            {
                if (item != null)
                {
                    //this.myevent -= item.Show;
                    item.PropertyChanged -= Item_PropertyChanged;
                }

            }
            List.Clear();



        }


        private void ExcuteAddingNewItemCommand(object obj)
        {

        }

        public async void Update()
        {
            IsBackGround = true;
            List[0].point = await Task.Run(() =>
            {
                //SCPI调用
                Thread.Sleep(10000);

                return "1000";
            });
            IsBackGround = false;
        }

        public void Update1()
        {
            Debug.WriteLine("Update1. My Thread ID is :" + Thread.CurrentThread.ManagedThreadId);
            Task.Run(() =>
            {
                Debug.WriteLine("Update1-Task. My Thread ID is :" + Thread.CurrentThread.ManagedThreadId);

                ViewModel vm = List[0];
                IsBackGround = true;
                vm.point = "1000";
                IsBackGround = false;
            });

        }
    }

    public class ViewModel : ViewModelBase, ICloneable, IEditableObject
    {
        private DataInfo _dataInfo;

        private DisplayDataEnum _displayDataEnum;


        public ICommand UpCommand { private set; get; }

        public ICommand DownCommand { private set; get; }



        public DataInfo dataInfo
        {

            get
            {
                return _dataInfo;
            }
        }


        public ViewModel()
          : this(new DataInfo(), DisplayDataEnum.HZ)
        {

        }


        public ViewModel(DataInfo dataInfo, DisplayDataEnum displayDataEnum)
        {
            _dataInfo = dataInfo;
            _displayDataEnum = displayDataEnum;

            UpCommand = new RelayCommand<object>(ExcuteUp);
            DownCommand = new RelayCommand<object>(ExcuteDown);


            //var str = PropertyHelper.GetPropertyName<ViewModel>(u => u.start);
        }


        private string _start = "";

        public string start
        {

            get
            {
                if (!string.IsNullOrEmpty(_start))
                {
                    return _start;
                }
                else
                {
                    return ConvertDataToString(_dataInfo.start, _displayDataEnum);
                }
            }
            set
            {

                double temp = ConverStringToData(value, _displayDataEnum);
                if (temp != -1 && _dataInfo.start != temp)
                {
                    _dataInfo.start = temp;
                    _start = "";
                    RaisePropertyChanged();
                }
                else
                {
                    _start = value;
                }
            }
        }


        public string stop
        {

            get
            {

                return ConvertDataToString(_dataInfo.stop, _displayDataEnum);
            }
            set
            {
                double temp = ConverStringToData(value, _displayDataEnum);
                if (temp != -1 && _dataInfo.stop != temp)
                {
                    _dataInfo.stop = temp;
                    RaisePropertyChanged();
                }

            }
        }

        public string point
        {

            get
            {

                return _dataInfo.point.ToString();
            }
            set
            {
                int temp = 0;
                if (int.TryParse(value, out temp) && _dataInfo.point != temp)
                {
                    _dataInfo.point = temp;
                    RaisePropertyChanged();
                }

            }
        }


        private void ExcuteUp(object a)
        {
            string str = a as string;
            if (str != null)
            {
                var old = (double)_dataInfo.GetType().GetProperty(str).GetValue(_dataInfo);

                old += 1000;

                _dataInfo.GetType().GetProperty(str).SetValue(_dataInfo, old);

                RaisePropertyChanged(str);
            }
        }

        private void ExcuteDown(object a)
        {
            string str = a as string;
            if (str != null)
            {
                var old = (double)_dataInfo.GetType().GetProperty(str).GetValue(_dataInfo);

                old -= 1000;

                _dataInfo.GetType().GetProperty(str).SetValue(_dataInfo, old);

                RaisePropertyChanged(str);
            }


        }

        public string ConvertDataToString(double data, DisplayDataEnum displayDataEnum)
        {
            string str = "";

            switch (displayDataEnum)
            {
                case DisplayDataEnum.HZ:
                    str = CommonFunction.GetShowDataRepairPosition((decimal)data, CommonData.MarkerDataInputShowDigit);

                    break;

            }

            return str;
        }


        public double ConverStringToData(string str, DisplayDataEnum displayDataEnum)
        {
            double data = -1;
            //data = str switch
            //{
            //    var x when x.Contains("M") =>  { return  },
            //    _ => 0,
            //};

            if (str.Contains("k"))
            {

                data = double.Parse(StringHelper.RemoveNotNumber(str)) * 1000;
            }
            else if (str.Contains("M"))
            {
                data = double.Parse(StringHelper.RemoveNotNumber(str)) * 1000 * 1000;
            }



            return data;
        }

        public object Clone()
        {
            DataInfo dataInfo = (DataInfo)_dataInfo.Clone();




            ViewModel viewModel = new ViewModel(dataInfo, _displayDataEnum);

            return viewModel;
        }


        public void Show()
        {


        }

        public void BeginEdit()
        {

        }

        public void CancelEdit()
        {

        }

        public void EndEdit()
        {

        }
    }

    public class DataInfo
    {
        public double start { get; set; }

        public double stop { get; set; }

        public int point { get; set; }

        public object Clone()
        {
            return this.MemberwiseClone();
        }

        public DataInfo()
        {
            start = 300 * 1000;
            stop = 300 * 1000;
            point = 10;
        }
    }

    public class MyDataGrid : DataGrid
    {
        #region 成员变量
        private List<Key> ControlKeys = new List<Key> { Key.Enter, Key.Return, Key.M };

        private List<Key> InputKeys = new List<Key> { Key.D0, Key.D1, Key.D2, Key.D3, Key.D4, Key.D5, Key.D6, Key.D7, Key.D8, Key.D9 };


        private List<string> UnitStrs = new List<string> { "M", "k", "G" };

        private List<string> NumStrs = new List<string> { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        private ComboBox cb;

        private TextBox HideTB;

        #endregion

        public delegate void EditCompletedDelegate();
        public EditCompletedDelegate EditCompleted;

        #region 构造函数
        static MyDataGrid()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MyDataGrid), new FrameworkPropertyMetadata(typeof(MyDataGrid)));
        }

        public MyDataGrid()
        {
            this.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBox_TextChanged));


            EventManager.RegisterClassHandler(typeof(DataGrid), FrameworkElement.SizeChangedEvent, new RoutedEventHandler(OnSizeChanged));
            EventManager.RegisterClassHandler(typeof(ComboBox), FrameworkElement.LoadedEvent, new RoutedEventHandler(ComboBox_Loaded), true);
            EventManager.RegisterClassHandler(typeof(ComboBox), FrameworkElement.UnloadedEvent, new RoutedEventHandler(ComboBox_Unloaded), true);
            EventManager.RegisterClassHandler(typeof(TextBox), FrameworkElement.LoadedEvent, new RoutedEventHandler(TextBox_Loaded), true);


            Button button = new Button();


        }
        #endregion

        public bool IsCell(UIElement element)
        {
            return !(element == HideTB);
        }

        public bool IsEdit
        {
            get { return (bool)GetValue(IsEditProperty); }
            set { SetValue(IsEditProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsEdit.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsEditProperty =
            DependencyProperty.Register("IsEdit", typeof(bool), typeof(MyDataGrid), new PropertyMetadata(false, (sender, e) =>
             {
                 Debug.WriteLine("IsEdit:" + e.NewValue + "---date:" + DateTime.Now.ToString("HH:mm.fff"));

                 if (((MyDataGrid)sender).EditCompleted != null && !((bool)e.NewValue))
                     ((MyDataGrid)sender).EditCompleted();
             }));



        #region 附加属性
        #region MyInitialized Copy by gist.github.com/3104963
        public static readonly DependencyProperty MyInitializedProperty =
            DependencyProperty.RegisterAttached("MyInitialized", typeof(bool), typeof(MyDataGrid),
                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits, OnMyInitializedChanged));

        private static void OnMyInitializedChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs ev)
        {
            if ((bool)ev.NewValue == true)
            {
                // registering instance handler unbreaks class handlers
                if (dpo is ComboBox || dpo is TextBox)
                    (dpo as FrameworkElement).Loaded += EmptyRoutedEventHandler;

            }
            else
            {
                //throw new ArgumentException("Cannot set to false", ev.Property.Name);
            }
            //Console.WriteLine("MyInitialized {0} {1}=>{2}", dpo, ev.OldValue, ev.NewValue);
        }

        private static readonly RoutedEventHandler EmptyRoutedEventHandler = delegate { };

        public static void SetMyInitialized(UIElement element, bool value)
        {
            element.SetValue(MyInitializedProperty, value);
        }

        public static bool GetMyInitialized(UIElement element)
        {
            return (bool)element.GetValue(MyInitializedProperty);
        }
        #endregion
        #endregion

        #region 窗体事件
        private void OnSizeChanged(object sender, RoutedEventArgs e)
        {
            SetMyInitialized((DataGrid)sender, true);
        }


        protected override void OnExecutedCommitEdit(ExecutedRoutedEventArgs e)
        {
            base.OnExecutedCommitEdit(e);

            //Task.Run(() =>
            //{
            //    this.Dispatcher.Invoke((Action)delegate
            //    {
            //        int num = 0;
            //        while (num < 100)
            //        {
            //            if (!this.IsEditing())
            //            {
            //                if (EditCompleted != null)
            //                    EditCompleted();
            //                break;
            //            }

            //            num++;
            //            Thread.Sleep(10);
            //        }
            //    });
            //});
        }



        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            HideTB = this.GetTemplateChild("HideTB") as TextBox;
        }


        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            Key CurKey = e.Key == Key.ImeProcessed ? e.ImeProcessedKey : e.Key;

            Debug.WriteLine("OnPreviewKeyDown-----Key:" + CurKey + ";大写：" + e.KeyboardDevice.Modifiers + ";时间:" + DateTime.Now);

            if (ControlKeys.Contains(CurKey) || InputKeys.Contains(CurKey))
            {
                if (ControlKeys.Contains(CurKey) && !(e.KeyboardDevice.Modifiers == ModifierKeys.Shift) && (cb == null || (cb != null && !cb.IsDropDownOpen)))
                {

                    if (!this.IsEditing())
                    {
                        this.BeginEdit();
                    }
                    else
                    {
                        var uiElement = e.OriginalSource as UIElement;
                        if (uiElement != null)
                        {
                            uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                        }
                        this.CommitEdit();
                    }

                    e.Handled = true;
                }

                if (InputKeys.Contains(CurKey))
                {

                    if (!this.IsEditing())
                    {
                        this.BeginEdit();

                        var cell = this.GetDataGridCell(this.CurrentCell);
                        if (cell != null)
                        {
                            var tb = MyVisualTreeHelper.FindFirstVisualChild<TextBox>(cell);
                            if (tb != null)
                            {
                                tb.Focus();
                                tb.SelectAll();

                                tb.RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(tb), 0, CurKey) { RoutedEvent = Keyboard.PreviewKeyDownEvent });
                                tb.RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(tb), 0, CurKey) { RoutedEvent = Keyboard.PreviewKeyUpEvent });
                            }

                        }

                    }

                }
            }



            base.OnPreviewKeyDown(e);
        }


        private bool _justCreatedNewItem;

        protected override void OnInitializingNewItem(InitializingNewItemEventArgs e)
        {
            //object item = e.NewItem;

            //Task.Run((Action)delegate
            //{
            //    this.Dispatcher.BeginInvoke((Action)delegate
            //    {
            //        var dg = this.ContainerFromItem<DataGridRow>(item);
            //        if (dg != null)
            //        {
            //            var cell = this.GetCell(dg.GetIndex(), this.CurrentColumn.DisplayIndex);
            //            if (cell != null)
            //            {
            //                //cell.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
            //                //this.BeginEdit();

            //                #region 左键单击将光标切回上一行，并进入编辑态
            //                // cell.RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) { RoutedEvent = DataGridCell.MouseLeftButtonDownEvent });
            //                #endregion
            //                //#region 下移光标，生成CollectionView.NewItemPlaceholder
            //                this.RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(this), 0, Key.Enter) { RoutedEvent = Keyboard.KeyDownEvent });
            //                this.RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(this), 0, Key.Enter) { RoutedEvent = Keyboard.KeyUpEvent });
            //                //#endregion
            //                #region 左键单击将光标切回上一行，并进入编辑态
            //                cell.RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) { RoutedEvent = DataGridCell.MouseLeftButtonDownEvent });
            //                cell.RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) { RoutedEvent = DataGridCell.MouseLeftButtonDownEvent });
            //                #endregion
            //            }
            //        }

            //        //this.BeginEdit();
            //    });
            //});


            _justCreatedNewItem = true;

            base.OnInitializingNewItem(e);
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Reset:
                    var cell = this.GetCell(0, 0);
                    if (cell != null)
                        cell.Focus();
                    break;
                case NotifyCollectionChangedAction.Remove:
                    var iterator = e.OldItems.GetEnumerator();
                    while (iterator.MoveNext())
                    {
                        if (this.CurrentItem == iterator.Current)
                        {

                        }
                    }
                    break;

            }
            base.OnItemsChanged(e);
        }

        protected override void OnAddingNewItem(AddingNewItemEventArgs e)
        {
            e.NewItem = new ViewModel(new DataInfo { start = 1 }, DisplayDataEnum.HZ);
            base.OnAddingNewItem(e);
        }

        protected override void OnContextMenuOpening(ContextMenuEventArgs e)
        {
            DataGridCell cell = MyVisualTreeHelper.FindFirstVisualParent<DataGridCell>(e.OriginalSource as UIElement);
            DataGridRow row = MyVisualTreeHelper.FindFirstVisualParent<DataGridRow>(e.OriginalSource as UIElement);

            if (cell != null && row != null)
            {
                this.SelectedItem = row.Item;
                cell.Focus();
            }

            base.OnContextMenuOpening(e);
        }

        protected override void OnBeginningEdit(DataGridBeginningEditEventArgs e)
        {
            //IsEdit = true;
            if (_justCreatedNewItem)
            {
                this.CommitEdit(DataGridEditingUnit.Row, true);
                _justCreatedNewItem = false;
            }

            base.OnBeginningEdit(e);
        }

        protected override void OnCellEditEnding(DataGridCellEditEndingEventArgs e)
        {
            //IsEdit = false;
            base.OnCellEditEnding(e);
        }

        private void ComboBox_Loaded(object sender, RoutedEventArgs e)
        {
            cb = sender as ComboBox;
            if (cb != null)
            {
                cb.IsDropDownOpen = true;
                cb.Focus();
            }
        }

        private void TextBox_Loaded(object sender, RoutedEventArgs e)
        {
            TextBox tb = sender as TextBox;
            if (tb != null)
            {
                tb.Focus();
                tb.SelectAll();
            }
        }

        private void ComboBox_Unloaded(object sender, RoutedEventArgs e)
        {
            cb = null;
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox tb = e.OriginalSource as TextBox;
            if (tb != null && e.Changes.Count > 0)
            {
                TextChange textChange = e.Changes.ToList()[0];
                if (textChange.AddedLength > 0)
                {
                    string str = tb.Text.Substring(textChange.Offset, textChange.AddedLength);

                    if (UnitStrs.Contains(str))
                    {
                        var cell = MyVisualTreeHelper.FindFirstVisualParent<DataGridCell>(tb);
                        if (cell != null)
                        {
                            this.CommitEdit();
                            cell.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                        }
                    };

                    if (NumStrs.Contains(str))
                    {
                        string[] tempstrs = tb.Text.Remove(textChange.Offset, textChange.AddedLength).Split(" ");
                        if (tempstrs.Count() > 1)
                        {
                            tb.Text = tempstrs[0].Insert(textChange.Offset, str);
                            tb.SelectionStart = tb.Text.Count();
                        }
                    }
                }
                else if (textChange.RemovedLength > 0)
                {
                    string[] tempstrs = tb.Text.Split(" ");
                    if (tempstrs.Count() > 1)
                    {
                        tb.Text = tempstrs[0];
                        tb.SelectionStart = tb.Text.Count();
                    }
                }

            }
        }
        #endregion

        public void LostFocusNew()
        {
            this.HideTB?.Focus();
            this.CommitEdit();
        }
    }

    public static class DataGridPlus
    {
        /// <summary>  
        /// 获取DataGrid控件单元格  
        /// </summary>  
        /// <param name="dataGrid">DataGrid控件</param>  
        /// <param name="rowIndex">单元格所在的行号</param>  
        /// <param name="columnIndex">单元格所在的列号</param>  
        /// <returns>指定的单元格</returns>  
        public static DataGridCell GetCell(this DataGrid dataGrid, int rowIndex, int columnIndex)
        {
            try
            {
                DataGridRow rowContainer = dataGrid.GetRow(rowIndex);

                if (rowContainer != null && columnIndex != -1)
                {
                    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

                    if (presenter != null)
                    {
                        DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);

                        if (cell == null && dataGrid.Columns.Count > columnIndex)
                        {
                            dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[columnIndex]);
                            cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
                        }

                        return cell;
                    }
                }
            }
            catch (Exception)
            {

            }

            return null;
        }

        /// <summary>  
        /// 获取DataGrid的行  
        /// </summary>  
        /// <param name="dataGrid">DataGrid控件</param>  
        /// <param name="rowIndex">DataGrid行号</param>  
        /// <returns>指定的行号</returns>  
        public static DataGridRow GetRow(this DataGrid dataGrid, int rowIndex)
        {
            if (dataGrid == null || rowIndex == -1 || dataGrid.Items.Count - 1 < rowIndex)
                return null;

            DataGridRow rowContainer = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex);

            if (rowContainer == null && dataGrid.Items != null && dataGrid.Items.Count > rowIndex)
            {
                dataGrid.UpdateLayout();
                dataGrid.ScrollIntoView(dataGrid.Items[rowIndex]);
                rowContainer = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex);
            }

            return rowContainer;
        }

        /// <summary>  
        /// 获取父可视对象中第一个指定类型的子可视对象  
        /// </summary>  
        /// <typeparam name="T">可视对象类型</typeparam>  
        /// <param name="parent">父可视对象</param>  
        /// <returns>第一个指定类型的子可视对象</returns>  
        public static T GetVisualChild<T>(Visual parent) where T : Visual
        {
            T child = default(T);
            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);

            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null)
                {
                    child = GetVisualChild<T>(v);
                }
                if (child != null)
                {
                    break;
                }
            }

            return child;
        }


        public static DataGridCell GetDataGridCell(this DataGrid dataGrid, DataGridCellInfo cellInfo)
        {
            if (cellInfo.Column != null && cellInfo.Item != null)
            {
                var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
                if (cellContent != null)
                    return (DataGridCell)cellContent.Parent;
            }

            return null;
        }


        public static TContainer GetContainerFromIndex<TContainer>
    (this ItemsControl itemsControl, int index)
    where TContainer : DependencyObject
        {
            return (TContainer)
              itemsControl.ItemContainerGenerator.ContainerFromIndex(index);
        }


        public static TContainer ContainerFromItem<TContainer>
    (this ItemsControl itemsControl, object item)
    where TContainer : DependencyObject
        {
            itemsControl.UpdateLayout();
            return (TContainer)
              itemsControl.ItemContainerGenerator.ContainerFromItem(item);
        }

        public static bool IsEditing(this DataGrid dataGrid)
        {
            return dataGrid.GetEditingRow() != null;
        }

        public static DataGridRow GetEditingRow(this DataGrid dataGrid)
        {

            var sIndex = dataGrid.SelectedIndex;
            if (sIndex >= 0)
            {
                var selected = dataGrid.GetContainerFromIndex<DataGridRow>(sIndex);
                if (selected != null && selected.IsEditing) return selected;
            }

            for (int i = 0; i < dataGrid.Items.Count; i++)
            {
                if (i == sIndex) continue;
                var item = dataGrid.GetContainerFromIndex<DataGridRow>(i);
                if (item != null && item.IsEditing) return item;
            }

            //var SelectedItem = dataGrid.SelectedItem;
            //if (SelectedItem != null)
            //{
            //    var selected = dataGrid.ContainerFromItem<DataGridRow>(SelectedItem);
            //    if (selected != null && selected.IsEditing) return selected;
            //}

            //foreach (var item in dataGrid.Items)
            //{
            //    if (item == SelectedItem) continue;
            //    var item1 = dataGrid.ContainerFromItem<DataGridRow>(item);
            //    if (item1 != null && item1.IsEditing) return item1;
            //}



            return null;
        }

    }


    public class MUpDownTextBox : TextBox
    {

        #region 模板中的控件
        private RepeatButton UpBtn;
        private RepeatButton DownBtn;
        #endregion

        #region 构造函数
        static MUpDownTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MUpDownTextBox), new FrameworkPropertyMetadata(typeof(MUpDownTextBox)));
        }


        public MUpDownTextBox()
        {
        }
        #endregion

        #region 依赖属性
        public ICommand UpCommand
        {
            get { return (ICommand)GetValue(UpCommandProperty); }
            set { SetValue(UpCommandProperty, value); }
        }


        public static readonly DependencyProperty UpCommandProperty =
            DependencyProperty.Register("UpCommand", typeof(ICommand), typeof(MUpDownTextBox), new PropertyMetadata((ICommand)null));




        public ICommand DownCommand
        {
            get { return (ICommand)GetValue(DownCommandProperty); }
            set { SetValue(DownCommandProperty, value); }
        }


        public static readonly DependencyProperty DownCommandProperty =
            DependencyProperty.Register("DownCommand", typeof(ICommand), typeof(MUpDownTextBox), new PropertyMetadata((ICommand)null));




        public object CommandParameter
        {
            get { return (object)GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CommandParameter.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(MUpDownTextBox), new PropertyMetadata((object)null));




        public bool IsShowContextMenu
        {
            get { return (bool)GetValue(IsShowContextMenuProperty); }
            set { SetValue(IsShowContextMenuProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsShowContextMenu.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsShowContextMenuProperty =
            DependencyProperty.Register("IsShowContextMenu", typeof(bool), typeof(MUpDownTextBox), new PropertyMetadata(false, (sender, e) =>
             {
                 ContextMenu contextMenu = new ContextMenu();
                 MenuItem menuItem = new MenuItem();
                 //menuItem


             }));



        #endregion

        #region 路由事件
        public static readonly RoutedEvent UpEvent = EventManager.RegisterRoutedEvent("UpClick", RoutingStrategy.Bubble, typeof(EventHandler<RoutedEventArgs>), typeof(MUpDownTextBox));


        public event RoutedEventHandler UpClick
        {
            add
            {
                this.AddHandler(UpEvent, value);
            }
            remove
            {
                this.RemoveHandler(UpEvent, value);
            }
        }

        public static readonly RoutedEvent DownEvent = EventManager.RegisterRoutedEvent("DownClick", RoutingStrategy.Bubble, typeof(EventHandler<RoutedEventArgs>), typeof(MUpDownTextBox));


        public event RoutedEventHandler DownClick
        {
            add
            {
                this.AddHandler(DownEvent, value);
            }
            remove
            {
                this.RemoveHandler(DownEvent, value);
            }
        }
        #endregion

        #region 窗体事件
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            UpBtn = this.GetTemplateChild("UpBtn") as RepeatButton;
            if (UpBtn != null)
                UpBtn.Click += UpBtn_Click;
            DownBtn = this.GetTemplateChild("DownBtn") as RepeatButton;
            if (DownBtn != null)
                DownBtn.Click += DownBtn_Click; ;
        }

        private void UpBtn_Click(object sender, RoutedEventArgs e)
        {
            RoutedEventArgs args = new RoutedEventArgs(UpEvent, this);

            this.RaiseEvent(args);

            if (UpCommand != null && CommandParameter != null)
                UpCommand.Execute(CommandParameter);
        }

        private void DownBtn_Click(object sender, RoutedEventArgs e)
        {
            RoutedEventArgs args = new RoutedEventArgs(DownEvent, this);

            this.RaiseEvent(args);


            if (DownCommand != null && CommandParameter != null)
                DownCommand.Execute(CommandParameter);
        }


        protected override void OnKeyUp(KeyEventArgs e)
        {


            base.OnKeyUp(e);
        }


        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            Debug.WriteLine("MUpDownTextBox-OnPreviewKeyDown---key:" + e.Key + "---dateTime:" + DateTime.Now.ToString("HH:mm.fff"));
            switch (e.Key)
            {
                case Key.Up:
                    UpBtn_Click(this, e);
                    break;
                case Key.Down:
                    DownBtn_Click(this, e);
                    break;

            }

            base.OnPreviewKeyDown(e);
        }



        protected override void OnMouseWheel(MouseWheelEventArgs e)
        {
            if (e.Delta > 0)
            {
                UpBtn_Click(this, e);
            }
            else
            {
                DownBtn_Click(this, e);
            }

            base.OnMouseWheel(e);
        }
        #endregion
    }


    public class GetTextBindPathConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                if (value is MUpDownTextBox)
                {
                    MUpDownTextBox tb = value as MUpDownTextBox;

                    return tb.GetBindingExpression(TextBox.TextProperty).ParentBinding.Path.Path;
                }
                else
                    return "";
            }
            catch
            {
                return "";
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }



    public class StringHelper
    {


        /// <summary>
        /// 去掉字符串中的数字
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string RemoveNumber(string key)
        {
            return Regex.Replace(key, @"\d", "");
        }



        /// <summary>
        /// 去掉字符串中的非数字
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string RemoveNotNumber(string key)
        {
            string str = Regex.Replace(key, @"[^\d.]*", "");

            return str;

        }
    }


    public class PropertyHelper
    {

        public static string GetPropertyName<T>(Expression<Func<T, string>> expr)
        {
            var name = ((MemberExpression)expr.Body).Member.Name;
            return name;
        }

    }
}
